from flask import current_app
from flask import g, jsonify
from flask import redirect
from flask import request
from flask import session

from info import constants
from info import db
from info.models import User, News, Category
from info.utils.commons import user_login_data
from info.utils.image_storage import image_storage
from info.utils.response_code import RET
from . import profile_blue
from flask import render_template

#功能描述：获取我的关注
# 请求路径: /user/user_follow
# 请求方式: GET
# 请求参数:p
# 返回值: 渲染user_follow.html页面,字典data数据
@profile_blue.route('/user_follow')
@user_login_data
def user_follow():
    #1.获取参数
    page = request.args.get("p","1")
    #2.参数类型转换
    try:
        page = int(page)
    except Exception as e:
        page = 1

    #3.分页查询
    try:
        paginate = g.user.followed.paginate(page,2,False)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg="获取用户失败")
    #4.获取分页对象属性,总页数,当前页,对象列表
    totalPage = paginate.pages
    currentPage = paginate.page
    items = paginate.items

    #5.用户对象列表转成字典列表
    users_list = []
    for item in items:
        users_list.append(item.to_dict())
    #6.携带数据，渲染页面
    data = {
        "totalPage":totalPage,
        "currentPage":currentPage,
        "users_list":users_list
    }
    return render_template("news/user_follow.html",data=data)


#功能描述：作者新闻列表获取
# 请求路径: /user/other_news_list
# 请求方式: GET
# 请求参数:p,user_id
# 返回值: errno,errmsg
@profile_blue.route('/other_news_list')
def other_news_list():
    #1.获取参数
    page = request.args.get("p","1")
    author_id = request.args.get("user_id")

    #2.参数为空校验,参数类型转换
    if not author_id:
        return jsonify(errno=RET.PARAMERR,errmsg="参数不全")

    try:
        page = int(page)
    except Exception as e:
        page = 1

    #3.根据作者编号，取出作者对象，判断作者对象是否存在
    try:
        author = User.query.get(author_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg="获取作者失败")

    if not author:
        return jsonify(errno=RET.NODATA,errmsg="作者不存在")

    #4.分页查询作者的新闻列表
    try:
        paginate = author.news_list.order_by(News.create_time.desc()).paginate(page, 3, False)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg="获取新闻失败")

    #5.获取分页对象属性
    total_page = paginate.pages
    current_page = paginate.page
    items = paginate.items

    #6.新闻对象列表转成字典列表
    news_list = []
    for item in items:
        news_list.append(item.to_dict())

    #7.携带数据，返回响应

    data = {
        "total_page":total_page,
        "current_page":current_page,
        "news_list":news_list
    }
    return jsonify(errno=RET.OK,errmsg="操作成功",data=data)


#功能描述：获取作者详情
# 请求路径: /user/other
# 请求方式: GET
# 请求参数:id
# 返回值: 渲染other.html页面,字典data数据
@profile_blue.route('/other')
@user_login_data
def other():
    #1.获取参数
    author_id = request.args.get("id")
    #2.校验参数，为空校验
    if not author_id:
        return jsonify(errno=RET.PARAMERR,errmsg="参数不全")

    #3.根据编号取出作者对象，判断作者是否存在
    try:
        author = User.query.get(author_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DATAERR,errmsg="获取作者失败")

    if not author:
        return jsonify(errno=RET.NODATA,errmsg="该作者不不存在")

    #4.判断该用户是否关注过该新闻的作者
    is_followed = False
    if g.user:
        if g.user in author.followers:
            is_followed = True

    #5.携带作者数据，渲染页面

    data = {
        "author":author.to_dict(),
        "user_info":g.user.to_dict() if g.user else "",
        "is_followed":is_followed
    }

    return render_template("news/other.html",data=data)


#功能描述：获取发布的新闻列表
# 请求方式:GET
# 请求参数:p
# 返回值:GET渲染user_news_list.html页面

@profile_blue.route('/news_list')
@user_login_data
def news_list():
    #1.获取参数
    page = request.args.get("p")
    #2.参数类型转换
    try:
        page = int(page)
    except Exception as e:
        page = 1

    #3.分页查询
    try:
        paginate = News.query.filter(News.user_id == g.user.id).order_by(News.create_time.desc()).paginate(page,3,False)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg="获取新闻失败")

    #4.获取分页查询属性
    totalPage = paginate.pages
    currentPage = paginate.page
    items = paginate.items

    #5.对象列表转成字典列表
    news_list = []
    for item in items:
        news_list.append(item.to_review_dict())
    #6.拼接数据，渲染页面
    data = {
        "totalPage":totalPage,
        "currentPage":currentPage,
        "news_list":news_list
    }
    return render_template("news/user_news_list.html",data=data)


#功能描述：新闻发布
# 请求路径: /user/news_release
# 请求方式:GET,POhuoqu fabu de ST
# 请求参数:GET无, POST ,title, category_id,digest,index_image,content
# 返回值:GET请求,user_news_release.html, data分类列表字段数据, POST,errno,errmsg

@profile_blue.route('/news_release', methods=['GET', 'POST'])
@user_login_data
def news_release():
    #1.如果是GET请求，携带数据渲染页面
    if request.method == "GET":
        try:
            categories = Category.query.all()
        except Exception as e:
            current_app.logger.error(e)
            return jsonify(errno=RET.DBERR,errmsg="获取分类失败")
        category_list = []
        for category in categories:
            category_list.append(category.to_dict())
        return render_template("news/user_news_release.html",categories=category_list)
    #2.POST请求，获取参数
    title = request.form.get("title")
    category_id = request.form.get("category_id")
    digest = request.form.get("digest")
    index_image = request.files.get("index_image")
    content = request.form.get("content")
    #3.校验参数，为空校验
    if not all([title,category_id,digest,index_image,content]):
        return jsonify(errno=RET.PARAMERR,errmsg="参数不全")
    #4.上传图片，并判断是否上传成功
    try:
        image_name = image_storage(index_image.read())
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.THIRDERR,errmsg="七牛云上传失败")

    if not image_name:
        return jsonify(errno=RET.NODATA,errmsg="图片上传失败")

    #5.创建新闻对象，设置新闻属性
    news = News()
    news.title = title
    news.source = g.user.nick_name
    news.digest = digest
    news.content = content
    news.index_image_url = constants.QINIU_DOMIN_PREFIX + image_name
    news.category_id = category_id
    news.user_id = g.user.id
    news.status = 1 #审核中

    #6.保存新闻到数据库
    try:
        db.session.add(news)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR,errmsg="新闻发布失败")
    #7.返回响应
    return jsonify(errno=RET.OK,errmsg="新闻发布成功")

#功能描述：获取我的收藏
# 请求路径: /user/collection
# 请求方式:GET
# 请求参数:p(页数)
# 返回值: user_collection.html页面
@profile_blue.route('/collection')
@user_login_data
def collection():
    #1.获取参数
    page = request.args.get("p","1")
    #2.参数类型转换
    try:
        page = int(page)
    except Exception as e:
        page = 1

    #3.分页查询
    try:
        paginate = g.user.collection_news.order_by(News.create_time.desc()).paginate(page,2,False)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg="获取新闻失败")
    #4.获取分页对象属性,总页数,当前页,对象列表
    totalPage = paginate.pages
    currentPage = paginate.page
    items = paginate.items

    #5.新闻对象列表转成字典列表
    news_list = []
    for item in items:
        news_list.append(item.to_dict())
    #6.携带数据，渲染页面
    data = {
        "totalPage":totalPage,
        "currentPage":currentPage,
        "news_list":news_list
    }
    return render_template("news/user_collection.html",data=data)

#功能描述：修改密码
# 请求路径: /user/pass_info
# 请求方式:GET,POST
# 请求参数:GET无, POST有参数,old_password, new_password
# 返回值:GET请求: user_pass_info.html页面,data字典数据, POST请求: errno, errmsg
@profile_blue.route('/pass_info', methods=['GET', 'POST'])
@user_login_data
def pass_info():
    #1.如果是GET请求，渲染页面
    if request.method == "GET":
        return render_template("news/user_pass_info.html")
    #2.如果是POST请求，获取参数
    old_password = request.json.get("old_password")
    new_password = request.json.get("new_password")
    #3.参数校验，为空校验
    if not all([old_password,new_password]):
        return jsonify(errno=RET.PARAMERR,errmsg="参数不全")
    #4.判断旧密码是否正确
    if not g.user.check_password(old_password):
        return jsonify(errno=RET.DATAERR,errmsg="旧密码错误")

    #5.设置新密码到用户对象
    g.user.password = new_password

    #5.1　清除用户登陆信息
    session.pop("user_id",None)
    session.pop("nick_name",None)
    session.pop("mobile",None)
    #6.返回响应
    return jsonify(errno=RET.OK,errmsg="修改成功")

#功能描述：图片上传
# 请求路径: /user/pic_info
# 请求方式:GET,POST
# 请求参数:无, POST有参数,avatar
# 返回值:GET请求: user_pci_info.html页面,data字典数据, POST请求: errno, errmsg,avatar_url
@profile_blue.route('/pic_info', methods=['GET', 'POST'])
@user_login_data
def pic_info():
    #1.判断如果是GET请求，携带用户数据渲染界面
    if request.method == "GET":
        return render_template("news/user_pic_info.html",user = g.user.to_dict())
    #2.如果是POST请求，获取参数
    avatar = request.files.get("avatar")
    #3.校验参数
    if not avatar:
        return jsonify(errno=RET.PARAMERR,errmsg="参数不全")
    #4.上传图片，判断是否上传成功
    try:
        image_name = image_storage(avatar.read())
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.THIRDERR,errmsg="七牛云异常")

    if not image_name:
        return jsonify(errno=RET.NODATA,errmsg="图片上传失败")
    #5.设置图片到用户对象
    g.user.avatar_url = image_name
    #6.返回响应，返回图片地址
    data = {
        "avatar_url":constants.QINIU_DOMIN_PREFIX + image_name
    }
    return jsonify(errno=RET.OK,errmsg="上传成功",data=data)

# 功能描述：用户信息基本展示
# 请求路径: /user/base_info
# 请求方式:GET,POST
# 请求参数:POST请求有参数,nick_name,signature,gender
# 返回值:errno,errmsg

@profile_blue.route('/base_info', methods=['GET', 'POST'])
@user_login_data
def base_info():

    #1.判断如果是GET请求，携带数据展示页面
    if request.method == "GET":
        return render_template("news/user_base_info.html",user=g.user.to_dict())

    #2.如果是POST请求，获取参数
    nick_name = request.json.get("nick_name")
    signature = request.json.get("signature")
    gender = request.json.get("gender")

    #3.校验参数，为空校验
    if not all([nick_name,signature,gender]):
        return jsonify(errno=RET.PARAMERR,errmsg="参数不全")

    #4.性别校验
    if not gender in ["MAN","WOMAN"]:
        return jsonify(errno=RET.DATAERR,errmsg="性别异常")

    #5.更新数据到用户对象中
    try:

        g.user.nick_name = nick_name
        g.user.signature = signature
        g.user.gender = gender

        db.session.commit()

    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg="修改失败")

    #6.返回响应
    return jsonify(errno=RET.OK,errmsg="修改成功")

# 功能描述：用户界面展示
# 请求路径: /user/info
# 请求方式:GET
# 请求参数:无
# 返回值: user.html页面,用户字典data数据
@profile_blue.route('/info')
@user_login_data
def user_info():

    # 判断用户是否登陆
    if not g.user:
        return redirect("/")

    data = {
        "user_info":g.user.to_dict()
    }
    return render_template("news/user.html",data=data)